/*
 * Copyright (C) 2015  Vialatte Romain <romain.vialatte@ecole.ensicaen.fr>
 * Copyright (C) 2016  Nicola Spanti (RyDroid) <dev@nicola-spanti.info>
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */


#include <check.h>
#include "PlanetWars2dRT-core/specific/model/game_default.h"
#include "PlanetWars2dRT-core/specific/model/game_players.h"
#include "PlanetWars2dRT-core/utils/color_rgb_const.h"


struct game_t   a_game;
struct player_t a_human;

void
tests_setup_init(void)
{
  game_init_first_time_only_default(&a_game);
  
  a_human.name = NULL;
  a_human.act  = NULL;
}

void
tests_setup_free(void)
{
  game_destructor(&a_game);
}


START_TEST(test_add_correct_player)
{
  player_set_name(&a_human, "Romain");
  a_human.color = COLOR_RGB_BLUE;
  ck_assert(game_add_player(&a_game, &a_human));
  ck_assert_uint_lt(game_get_nb_players(&a_game), NB_MAX_PLAYERS);
}
END_TEST

START_TEST(test_add_correct_players)
{
  player_set_name(&a_human, "Anthony");
  a_human.color = COLOR_RGB_BLUE;
  ck_assert(game_add_player(&a_game, &a_human));
  ck_assert_uint_lt(game_get_nb_players(&a_game), NB_MAX_PLAYERS);
  
  player_set_name(&a_human, "Sarah");
  a_human.color = COLOR_RGB_GREEN;
  ck_assert(game_add_player(&a_game, &a_human));
  ck_assert_uint_lt(game_get_nb_players(&a_game), NB_MAX_PLAYERS);
  
  player_set_name(&a_human, "Nicola");
  a_human.color = COLOR_RGB_RED;
  ck_assert(game_add_player(&a_game, &a_human));
  ck_assert_uint_lt(game_get_nb_players(&a_game), NB_MAX_PLAYERS);
}
END_TEST

START_TEST(test_add_incorrect_players_same_name)
{	
  player_set_name(&a_human, "Anthony");
  a_human.color = COLOR_RGB_BLUE;
  ck_assert(game_add_player(&a_game, &a_human));
  ck_assert_uint_lt(game_get_nb_players(&a_game), NB_MAX_PLAYERS);
  
  player_set_name(&a_human, "Anthony");
  a_human.color = COLOR_RGB_GREEN;
  ck_assert(!game_add_player(&a_game, &a_human));
  ck_assert_uint_lt(game_get_nb_players(&a_game), NB_MAX_PLAYERS);
}
END_TEST

START_TEST(test_add_incorrect_players_same_color)
{
  player_set_name(&a_human, "Sarah");
  a_human.color = COLOR_RGB_BLUE;
  ck_assert(game_add_player(&a_game, &a_human));
  ck_assert_uint_lt(game_get_nb_players(&a_game), NB_MAX_PLAYERS);
  
  player_set_name(&a_human, "Anthony");
  a_human.color = COLOR_RGB_BLUE;
  ck_assert(!game_add_player(&a_game, &a_human));
  ck_assert_uint_lt(game_get_nb_players(&a_game), NB_MAX_PLAYERS);
}
END_TEST


START_TEST(test_get_nb_players)
{
  ck_assert_uint_lt(game_get_nb_players(&a_game), NB_MAX_PLAYERS);
  
  game_remove_players(&a_game);
  ck_assert_uint_eq(game_get_nb_players(&a_game), 0);
  ck_assert_uint_lt(game_get_nb_players(&a_game), NB_MAX_PLAYERS);
  
  player_set_name(&a_human, "Richard Stallman");
  a_human.color = COLOR_RGB_BLUE;
  ck_assert(game_add_player(&a_game, &a_human));
  ck_assert_uint_eq(game_get_nb_players(&a_game), 1);
  ck_assert_uint_lt(game_get_nb_players(&a_game), NB_MAX_PLAYERS);
  
  player_set_name(&a_human, "Benjamin Bayart");
  a_human.color = COLOR_RGB_GREEN;
  ck_assert(game_add_player(&a_game, &a_human));
  ck_assert_uint_eq(game_get_nb_players(&a_game), 2);
  ck_assert_uint_lt(game_get_nb_players(&a_game), NB_MAX_PLAYERS);
  
  player_set_name(&a_human, "Bill Gates");
  a_human.color = COLOR_RGB_GREEN;
  ck_assert(!game_add_player(&a_game, &a_human));
  ck_assert_uint_eq(game_get_nb_players(&a_game), 2);
  
  player_set_name(&a_human, "Tim Cook");
  a_human.color = COLOR_RGB_GREEN;
  ck_assert(!game_add_player(&a_game, &a_human));
  ck_assert_uint_eq(game_get_nb_players(&a_game), 2);
  
  player_set_name(&a_human, "Jérémie Zimmermann");
  a_human.color = COLOR_RGB_WHITE;
  ck_assert(game_add_player(&a_game, &a_human));
  ck_assert_uint_eq(game_get_nb_players(&a_game), 3);
  ck_assert_uint_lt(game_get_nb_players(&a_game), NB_MAX_PLAYERS);
}
END_TEST

START_TEST(test_remove_players)
{
  game_remove_players(&a_game);
  ck_assert_uint_eq(game_get_nb_players(&a_game), 0);
  ck_assert_uint_lt(game_get_nb_players(&a_game), NB_MAX_PLAYERS);
  
  player_set_name(&a_human, "Hitler");
  a_human.color = COLOR_RGB_BLACK;
  ck_assert(game_add_player(&a_game, &a_human));
  game_remove_players(&a_game);
  ck_assert_uint_eq(game_get_nb_players(&a_game), 0);
  
  player_set_name(&a_human, "Hitler");
  a_human.color = COLOR_RGB_GRAY;
  ck_assert(game_add_player(&a_game, &a_human));
  player_set_name(&a_human, "Stalline");
  a_human.color = COLOR_RGB_RED;
  ck_assert(game_add_player(&a_game, &a_human));
  player_set_name(&a_human, "Franco");
  a_human.color = COLOR_RGB_BROWN;
  ck_assert(game_add_player(&a_game, &a_human));
  player_set_name(&a_human, "Darth Sidious");
  a_human.color = COLOR_RGB_BLACK;
  ck_assert(game_add_player(&a_game, &a_human));
  game_remove_players(&a_game);
  ck_assert_uint_eq(game_get_nb_players(&a_game), 0);
}
END_TEST


Suite*
game_players_suite(void)
{
  Suite* s = suite_create("Players of a game");
  
  TCase* tc_add_players = tcase_create("Add players");
  tcase_add_checked_fixture(tc_add_players,
			    tests_setup_init, tests_setup_free);
  tcase_add_test(tc_add_players, test_add_correct_player);
  tcase_add_test(tc_add_players, test_add_correct_players);
  tcase_add_test(tc_add_players, test_add_incorrect_players_same_name);
  tcase_add_test(tc_add_players, test_add_incorrect_players_same_color);
  suite_add_tcase(s, tc_add_players);
  
  TCase* tc_players_others = tcase_create("Others functions related to players");
  tcase_add_checked_fixture(tc_players_others,
			    tests_setup_init, tests_setup_free);
  tcase_add_test(tc_players_others, test_get_nb_players);
  tcase_add_test(tc_players_others, test_remove_players);
  suite_add_tcase(s, tc_players_others);
  
  return s;
}

int
main(void)
{
  size_t number_failed;
  Suite* s;
  SRunner* sr;
  
  s = game_players_suite();
  sr = srunner_create(s);
  
  srunner_run_all(sr, CK_NORMAL);
  number_failed = srunner_ntests_failed(sr);
  srunner_free(sr);
  
  return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
